TimeCode Media HandlerThe TimeCode Media Handler provides a way to store time code in a QuickTime movie. This media supports SMPTE time code. Typically, an application will add a timecode track when a movie is captured. Since the time code is maintained during Movie editing, it can be queried later to produce an edit list.TimeCode TrackThe information stored in the TimeCode track consists of source identification information (eg. name of the source tape), format information (eg. 29.97 fps, dropframe, etc), and frame numbers (ie. translates into time code given the format information). In a perfect world, you only need to record the time code information for the first frame of a captured movie. Let’s say that the first frame is at time 00:02:13:15 (HH:MM:SS:FF). You record this as a sample in the time code track and this sample lasts for the duration of the movie. Then you can determine the time code for every frame in the movie. In the real world, you may encounter discontinous time code. In this case, you would add another time code sample whenever the discontinuity occurs.Since the duration of a sample is specified when it is added to a track, you must know the duration the time code is for. You have to add the time code sample after you know how long it is good for.Source IdentificationThe source identification information is stored in the TimeCodeDescription. This information is stored as UserData identifying the source material. Use the Movie Toolbox UserData routines to extract and add this information. Use the ‘name’ type to specify the name of the source material as UserDataText. Other information about the source may be stored here in the future. See the “Working With Movie User Data” section inside Chapter 2 of Inside Macintosh QuickTime.struct TimeCodeDescription { // standard sample description header long descSize; long dataFormat; long resvd1; short resvd2; short dataRefIndex; // timecode specific stuff long flags; TimeCodeDef timeCodeDef; UserDataAtom srcRef;};The TimeCodeDef structure defines the format of the the time code that was added to the TimeCode track. struct TimeCodeDef { long flags; TimeScale fTimeScale; TimeValue frameDuration; unsigned char numFrames;};enum { tcDropFrame = 1<<0, tc24HourMax = 1<<1, tcNegTimesOK = 1<<2, tcCounter = 1<<3};The tcDropFrame bit in the flags field defines whether the time code was drop frame. The tc24HourMax bit specifies whether the time code wraps at 24 hours (eg. SMPTE). The tcNegTimesOK specifies that negative values are allowed (eg. -00:01:20:15). The tcCounter specifies that the time is a counter position of a tape.The fTimeScale field of TimeCodeDef is the time scale for interpreting frameDuration. FrameDuration is how long each frame lasts in real time. NumFrames is the number of frames per second for the timecode format. If the time is a counter, this is the number of frames per tick for each counter tick.For SMPTE NTSC 29.97 frames-per-second drop-frame, a TimeCodeDef would be:TimeCodeDef.flags = tcDropFrame | tc24HourMax; TimeCodeDef.fTimeScale= 2997; TimeCodeDef.frameDuration= 100;TimeCodeDef.numFrames= 30;The sample data is the frame number from time zero. For example, if the time code for the material is at 00:00:12:15 for the above TimeCodeDef, the frame number is 12*30+15 = 375. In other words, the beginning of the movie is frame number 375 which is the same as 00:00:12:15 when converted using the previous TimeCodeDef. The TimeCode Media Handler provides routines for doing all the conversions necessary. The sample data is just a long.Since the original TimeCodeDef is stored, you can readily use the same time code format as the original material. You can also interpret it in another form if you desire.When frame numbers are converted to and from time code using the TimeCodeDef, the time code is expressed using the TimeCodeRecord.struct TimeCodeTime { unsigned char hours; Boolean isNegative:1; unsigned char minutes:7; unsigned char seconds; unsigned char frames;};struct TimeCodeCounter { long counter;};union TimeCodeRecord{ TimeCodeTime t; TimeCodeCounter c;};Note: The interfaces do not define isNegative and minutes as bit fields for portability reasons. Instead, mask the minutes field with tctNegFlag to determine whether the time code is negative. TimeCodeRecordAs you can see, the TimeCodeRecord handles both time code and counter values. When you directly access a TimeCodeRecord as a TimeCodeTime, it is important to check the negative bit. The TimeCode Media Handler provides routines for converting frameNumbers to and from TimeCodeRecords.When a TimeCode track is added to a movie, it is vital to indicate which tracks this time code is for. You do this using the new track reference routines (see documention for this elsewhere). Study the code samples closely for adding to and extracting time codes from a movie. The AddTimeCode sample lets you add timecode to a movie. The ExportCMX3600 sample is a QuickTime Movie Export Component which creates a CMX3600 EDL for a Movie with TimeCode.You can have the time code displayed in the Movie. When displayed, the time code appears in the Track’s rectangle. You must enable the track as well as call TCSetTimeCodeFlags. To turn off the display, disable the track and call TCSetTimeCodeFlags.Callspascal HandlerError TCGetCurrentTimeCode( MediaHandler mh, long *frameNum, TimeCodeDef *tcdef, TimeCodeRecord *tcrec, UserData *srcRef);This call returns all the information about the TimeCode for the current time in the movie. It returns the frameNumber, the TimeCodeDef, the TimeCodeRecord interpreting the frameNumber using the TimeCodeDef, and the SourceReference. If there are any pieces of information you do not need, just pass nil. If you get a srcRef, don’t forget to call DisposeUserData after you are finished with it.pascal HandlerError TCGetTimeCodeAtTime( MediaHandler mh, const TimeValue mediaTime, long *frameNum, TimeCodeDef *tcdef, TimeCodeRecord *tcdata, UserData *srcRef );This call returns all the information about the TimeCode at a given time in the media. It returns the frameNumber, the TimeCodeDef, the TimeCodeRecord interpreting the frameNumber using the TimeCodeDef, and the SourceReference. If there are any pieces of information you do not need, just pass nil. If you get a srcRef, don’t forget to call DisposeUserData after you are finished with it.pascal HandlerError TCTimeCodeToFrameNumber( MediaHandler mh, TimeCodeDef *tcdef, TimeCodeRecord *tcrec, long *frameNumber )This call converts the TimeCodeRecord into a frameNumber using the TimeCodeDef. pascal HandlerError TCFrameNumberToTimeCode( MediaHandler mh, long frameNumber, TimeCodeDef *tcdef, TimeCodeRecord *tcrec )This call converts the frameNumber into a TimeCodeRecord using the TimeCodeDef. pascal HandlerError TCTimeCodeToString( MediaHandler mh, const TimeCodeDef *tcdef, const TimeCodeRecord *tcrec, StringPtr tcStr )This call creates a string for the TimeCodeRecord using the TimeCodeDef. If the time code is drop-frame, the separators are ‘;’ instead of ‘:’. pascal HandlerError TCGetSourceRef( MediaHandler mh, const TimeCodeDescriptionHandle tcdH, UserData *srefH )This call returns the SourceRefence from the TimeCodeDescription. After you are done with srefH, don’t forget to call DisposeUserData on it. pascal HandlerError TCSetSourceRef( MediaHandler mh, TimeCodeDescriptionHandle tcdH, UserData srefH )This call puts srefH into the TimeCodeDescription. pascal HandlerError TCSetTimeCodeFlags( MediaHandler mh, long flags, long flagsMask )This call sets flags for the TimeCode media. Currently the only flag is whether to display the time code in the movie. pascal HandlerError TCGetTimeCodeFlags( MediaHandler mh, long *flags )This call returns the flags for the TimeCode media. Currently the only flag is whether to display the time code in the movie. pascal HandlerError TCSetDisplayOptions( MediaHandler mh, const TCTextOptionsPtr textOptions )This call sets the display options for the TimeCode media. If the time code is displayed in the movie, these options control its characteristics. The TCTextOptions defines the text characteristics used when timecode is displayed. struct TCTextOptions { short txFont; short txFace; short txSize; RGBColor foreColor; RGBColor backColor;};pascal HandlerError TCGetDisplayOptions( MediaHandler mh, TCTextOptionsPtr textOptions )This call returns the display options for the TimeCode media. If the time code is displayed in the movie, these options control its characteristics. Ó ◊# ˇ ˇˇˇˇ # ◊